package constraints_validator;
import java.io.IOException;
import java.util.List;

import reader.InstanceReader;
import value_object.InstanceVO;
import value_object.SolutionVO;
import value_object.data.Acquisition;
import value_object.data.Strip;

/**
 * This class is mainly used to validate the solution if it respects the 4 constraints
 */
public class ValidatorSolution {
	
	/**
	 * validate constraint 1
	 * @param instance
	 * @param solution
	 * @return true if the solution respects the constraint 1
	 */
	public static boolean validateConstraint1(InstanceVO instance, SolutionVO solution) {
		List<Strip> stripList = instance.getStripListFrom(solution);
		for (Strip strip : stripList) {
			if (!strip.validateConstraint1())
				return false;
		}
		return true;
	}	
	
	/**
	 * validate constraint 2
	 * @param instance
	 * @param solution
	 * @return true if the solution respects the constraint 2
	 */
	public static boolean validateConstraint2(InstanceVO instance, SolutionVO solution) {
		List<Strip> stripList = instance.getStripListFrom(solution);
		for (int i = 0; i < stripList.size() - 1; i++) {
			Strip previousStrip = stripList.get(i);
			Strip currentStrip = stripList.get(i + 1);
//			System.out.println("PreviousStrip = "+ previousStrip.getStrip_index() + " - CurrentStrip = "+ currentStrip.getStrip_index());
			if (!currentStrip.validateConstraint2(previousStrip))
				return false;
		}
		return true;
	}

	/**
	 * validate constraint 3
	 * @param instance
	 * @param solution
	 * @return true if the solution respects the constraint 3
	 */
	public static boolean validateConstraint3(InstanceVO instance, SolutionVO solution) {
		List<Acquisition> acqList = solution.getAcquisitionList();
		
		for (int i = 0; i < acqList.size() - 1; i++) {
			for (int j = i + 1; j < acqList.size(); j++){
//				System.out.println(" Strip index previous = "+ acqList.get(i).getStrip_index()+" - Strip index current = " + acqList.get(j).getStrip_index());
				if (acqList.get(i).getStrip_index() == acqList.get(j).getStrip_index())
					return false;
				}
		}
		return true;
	}	
	
	/**
	 * validate constraint 4
	 * @param instance
	 * @param solution
	 * @return true if the solution respects the constraint 4
	 */
	public static boolean validateConstraint4(InstanceVO instance, SolutionVO solution) {
		List<Strip> stripList = instance.getStripListFrom(solution);
		
		for (int i = 0; i < stripList.size() - 1; i++) {
			for (int j = i + 1; j < stripList.size(); j++) {
				Strip strip1 = stripList.get(i);
				Strip strip2 = stripList.get(j);
				if ((strip1.getRequest_index() == strip2.getRequest_index()) //belong to the same stereo request
						&& (strip1.getTwin_strip_index() == strip2.getStrip_index() || strip2.getTwin_strip_index() == strip1.getStrip_index()) 
						&& (strip1.getStrip_direction() != strip2.getStrip_direction())) {					
					return false;
				}
			}
		}
		return true;
	}
	
	/**
	 * Verify solution
	 * 
	 * @param instance
	 * @param solution
	 * @return true if the solution respects all the 4 constraints
	 */
	public static boolean verifySolution(InstanceVO instance, SolutionVO solution){
		if(validateConstraint1(instance, solution)
		 && validateConstraint2(instance, solution)
		 && validateConstraint3(instance, solution)
		 && validateConstraint4(instance, solution))
			return true;
		
		return false;
	}
	
	
	/**
	 * For Test... - Verify the constraint 4
	 * @param args
	 * @throws IOException
	 */
	
	public static void main(String[] args) throws IOException {
		
		int data_set_number = 2, grid_number = 9,  track_number = 170;

		InstanceReader instanceReader = new InstanceReader();
		InstanceVO instance = new InstanceVO();
		
		instance = instanceReader.readInstance(data_set_number, grid_number, track_number);
		
		//Verify constraint 4 with the instance file instance_2_9_170
		//The couple of strip (7,16) will be in the same direction
		//The couple of strip (8,17) will be in the same direction
		//The couple of strip (9,18) will be in the same direction
		//The couple of strip (10,20) will be in the same direction
		
		SolutionVO solution = new SolutionVO();
		int[] strip_index = {7, 8, 17, 9, 18, 10, 20}; 
		int[] acquisition_direction = {1, 0, 0, 1, 1, 0, 0};
		
		for (int i = 0; i < strip_index.length; i++) {
			Acquisition acq = new Acquisition(strip_index[i], acquisition_direction[i]);
			solution.addAcquisition(acq);
		}
		
		System.out.println("Validate constraint 4 = "+ validateConstraint4(instance, solution));
		System.out.println("Validate constraint 4 = "+ validateConstraint1(instance, solution));
		
	}
}
